package com.example.mq.emqx;

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

/**
 * @author Jason
 * @PACKAGE_NAME com.example.emqx
 * @Description mqtt发布端
 * @date 2023-11-18 14:31
 */
public class Publisher {
    public static void main(String[] args) {
        // MQTT 主题 -> 定义发布消息的主题
        String topic = "test/topic";
        // 发布的内容 -> 定义要发布的消息内容
        String content = "Hello MQTT";
        // 服务质量（QoS）级别 -> 设置消息的服务质量级别（0, 1, 或 2）
        int qos = 2;
        // MQTT 代理地址 -> 指定 MQTT 代理服务器的地址和端口
        String broker = "tcp://localhost:1883";
        // 客户端 ID -> 为这个 MQTT 客户端实例指定一个唯一的标识符
        String clientId = "JavaPublisher";
        // 持久化存储，这里使用内存持久化 -> 使用内存持久化来存储会话和消息，避免依赖文件存储
        MemoryPersistence persistence = new MemoryPersistence();

        try {
            // 创建 MQTT 客户端 -> 实例化 MQTT 客户端，指定代理地址、客户端 ID 和持久化类型
            MqttClient client = new MqttClient(broker, clientId, persistence);
            // 连接选项，设置清除会话（Clean Session） -> 设置连接选项，其中清除会话确保每次连接都是一个新会话
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);

            // 连接到 MQTT 代理 -> 建立与 MQTT 代理的连接
            System.out.println("正在连接代理: " + broker);
            client.connect(connOpts);
            System.out.println("已连接");

            // 发布消息 -> 发布指定内容的消息到指定的主题
            System.out.println("发布消息: " + content);
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            client.publish(topic, message);
            System.out.println("消息已发布");

            // 断开连接并退出 -> 断开与 MQTT 代理的连接并退出程序
            client.disconnect();
            System.out.println("已断开连接");
            System.exit(0);
        } catch (MqttException me) {
            // 处理连接过程中可能发生的异常 -> 捕获并处理建立连接或发布消息过程中可能出现的异常
            System.out.println("原因 " + me.getReasonCode());
            System.out.println("消息 " + me.getMessage());
            System.out.println("位置 " + me.getLocalizedMessage());
            System.out.println("原因 " + me.getCause());
            System.out.println("异常 " + me);
            me.printStackTrace();
        }

    }
}
